package com.aaa.cts.service.impl;

import com.aaa.common.bo.TreeNode;
import com.aaa.common.constants.ExceptionConstant;
import com.aaa.common.constants.ReturnStatus;
import com.aaa.common.util.CustomException;
import com.aaa.common.util.Result;
import com.aaa.cts.dao.MenuDao;
import com.aaa.cts.entity.Menu;
import com.aaa.cts.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2020-11-30 09:23:44
 */
@Service("menuService")
@Transactional
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuDao menuDao;

    @Override
    public Result queryUrlIsNotNull() {
        Menu menu = new Menu();
        menu.setUrl("url");
        menu.setVisible("0");
        List<Menu> menus = menuDao.queryAll(menu);
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(),menus);
    }

    /**
     * 查询所有节点数据
     * @return
     */
    @Override
    public Result queryNodes() {
        //获取数据集合
        List<TreeNode> treeNodes = menuDao.queryNodes();
        //定义返回集合
        List<TreeNode> treeNodeList=new ArrayList<>();
        //循环集合，绑定子节点
        if(treeNodes!=null && treeNodes.size()>0){
            for (TreeNode treeNode : treeNodes) {
                if(treeNode.getParentId()==0){
                    treeNodeList.add(treeNode);
                    //绑定子节点
                    bindChildren(treeNode,treeNodes);
                }
            }
        }
        //返回成功
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(),treeNodeList);
    }

    /**
     * 根据用户Id查询该用户所有节点数据
     * @param userId
     * @return
     */
    @Override
    public Result queryNodesByUserId(Integer userId) {
        //获取数据集合
        List<TreeNode> treeNodes = menuDao.queryNodesByUserId(userId);
        //定义返回集合
        List<TreeNode> treeNodeList=new ArrayList<>();
        //循环集合，绑定子节点
        if(treeNodes!=null && treeNodes.size()>0){
            for (TreeNode treeNode : treeNodes) {
                if(treeNode.getParentId()==0){
                    treeNodeList.add(treeNode);
                    //绑定子节点
                    bindChildren(treeNode,treeNodes);
                }
            }
        }
        //返回成功
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg(),treeNodeList);
    }

    public void bindChildren(TreeNode currentNode,List<TreeNode> treeNodes){
        //再次循环集合
        for (TreeNode treeNode : treeNodes) {
            //判断循环节点是否是当前节点的孩子，如果是加入
            if(treeNode.getParentId()==currentNode.getId()){
                List<TreeNode> children = currentNode.getChildren();
                //如果是第一个孩子，孩子集合为空，进行实例化
                if(children==null){
                    children=new ArrayList<>();
                }
                //添加孩子
                children.add(treeNode);
                //设置
                currentNode.setChildren(children);
                //递归找当前循环节点的孩子
                bindChildren(treeNode,treeNodes);
            }
        }
    }

    /**
     * 通过ID查询单条数据
     *
     * @param menuId 主键
     * @return 实例对象
     */
    @Override
    public Result queryById(Integer menuId) {
        if(menuId==null){
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(),
                    ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        Menu menu = this.menuDao.queryById(menuId);
        return new Result(ReturnStatus.SUCCESS.getReturnCode(), ReturnStatus.SUCCESS.getReturnMsg(),menu);
    }


    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<Menu> queryAllByLimit(int offset, int limit) {
        return this.menuDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param menu 实例对象
     * @return 实例对象
     */
    @Override
    public Menu insert(Menu menu) {
        this.menuDao.insert(menu);
        return menu;
    }

    /**
     * 修改数据
     *
     * @param menu 实例对象
     * @return 实例对象
     */
    @Override
    public Result update(Menu menu) {
        this.menuDao.update(menu);
        return this.queryById(menu.getMenuId());
    }

    /**
     * 通过主键删除数据
     *
     * @param menuId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer menuId)  {
        return this.menuDao.deleteById(menuId) > 0;
    }

    /**
     * 查询多条数据
     * @param menu 实例对象
     * @return Result --- Result.getData():treeNodeList
     */
    @Override
    public Result queryAllToTreeNode(Menu menu) {
        //把Menu集合转换为 List<TreeNode>
        List<Menu> menuList = this.menuDao.queryAlls(null);
        //实例化集合  用于接收数据
        List<TreeNode> treeNodeList = new ArrayList<>();
        TreeNode treeNode = null;
        //循环
        if (menuList != null && menuList.size() > 0) {
            for (Menu menuStr : menuList) {
                //查找一级节点
                if (menuStr.getParentId() == 0) {
                    treeNode = this.menuToTreeNode(menuStr);
                    //查找子节点
                    bindChildrens(treeNode, menuList);
                    treeNodeList.add(treeNode);
                }
            }
        }
        return new Result<>(ReturnStatus.SUCCESS.getReturnCode(), ReturnStatus.SUCCESS.getReturnMsg(), treeNodeList);
    }

    /**
     * @Author:
     * @Date : Created in
     * @Description :   封装一个Menu和TreeNode的转换
     * @Param :  menuStr
     * @Return :
     */
    private TreeNode menuToTreeNode(Menu menuStr) {
        TreeNode treeNode = new TreeNode();
        treeNode.setId(menuStr.getMenuId());
        treeNode.setParentId(menuStr.getParentId());
        treeNode.setLabel(menuStr.getMenuName());
        treeNode.setIcon(menuStr.getIcon());
        treeNode.setUrl(menuStr.getUrl());
        treeNode.setVisible(menuStr.getVisible());
        treeNode.setIndex(menuStr.getUrl());
        treeNode.setTitle(menuStr.getMenuName());
        return treeNode;
    }

    private void bindChildrens(TreeNode currentNode,List<Menu> menuList){
        //再次循环集合
        for (Menu menu : menuList) {
            //判断循环节点是否是当前节点的孩子
            if(currentNode.getId() == menu.getParentId()){
                List<TreeNode> children = currentNode.getChildren();
                //如果是第一个孩子，孩子结合为空，进行实例化
                if(children==null){
                    children = new ArrayList<>();
                }
                //添加孩子
                TreeNode treeNode = this.menuToTreeNode(menu);
                children.add(treeNode);
                //设置
                currentNode.setChildren(children);
                //递归找当前循环节点的孩子。。。
                bindChildrens(treeNode,menuList);
            }
        }
    }

    @Override
    public Result updateMenu(Map map) {
        if(map == null){
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(),
                    ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        this.menuDao.updateMenu(map);
        Integer menuId =(Integer) map.get("id");
        return this.queryById(menuId);
    }

    @Override
    public Result insertMenu(Map map) {
        if(map == null){
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(),
                    ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        menuDao.insertMenu(map);
        return new Result(ReturnStatus.SUCCESS.getReturnCode(),
                ReturnStatus.SUCCESS.getReturnMsg());
    }
}